package com.sentiment.algorithm;

import java.util.List;

import org.apache.log4j.Logger;
import org.bson.Document;

import com.sentiment.config.Config;
import com.sentiment.db.RalationMapDB;
import com.sentiment.db.SimilarityDB;
import com.sentiment.db.TextDB;
import com.sentiment.obj.RalationMap;
import com.sentiment.obj.Similarity;
import com.sentiment.obj.Text;

public class PageInOut {

	/*
	 * 该函数负责获取Lsh算法的输入 输入从相关数据库中获取 文章内容必须完整 包括 换行 需要传入用户输入的文章的id
	 */

	public void LshPageFromDB(String srcId) {
		Logger logger = Config.getLogger(this.getClass());
		LshCoreNo lsh = new LshCoreNo();
		String textname;	
		String pagetext;
		// 获得RalationMap数据库信息 一片源文章对应多少篇爬取的文章
		RalationMapDB rmdb = new RalationMapDB();
		RalationMap rm = rmdb.findDataByKeyAndVal("srcId", srcId);
		rmdb.DBClose();
		if (rm == null) {
			logger.error("-----[警告]数据库中未找到" + srcId + "对应的源文章-----");
			return;
		}
		int tarAmount = rm.getTarAmount();
		if (tarAmount == 0) {
			logger.error("-----[警告]该源文章" + srcId + "对应的爬取文章数为0-----");
			return;
		}
		int i = 0; // 标记属于第几篇文章
		// 获取爬取文章全部的id
		List<String> tarIdAll = rm.getTarIdAll();
		TextDB tdb = new TextDB();
		Text tx;
		while (i < tarAmount) { // while 循环获得爬取下来的每篇文章的标题和内容
			String tarId = tarIdAll.get(i);
			tx = tdb.findDataByKeyAndVal("id", tarId);
			if (tx == null) {
				logger.error("-----" + tarId + "未找到对应目标文章-----");
			} else {
				/*
				 * 这里获得爬取下来的每篇文章的标题和内容 ，直至所有文章获取通过
				 */
				textname = tx.getId(); // 输入每篇文章的标题(用id代替
				pagetext = Text.content2String(tx.getContent()); // 输入每篇文章的内容
//				logger.info("----- 以下是待检测文章 : "+tx.getTitle()+"的内容-----");
//				logger.info(pagetext);
				
				lsh.createTableSin(pagetext, textname, i);
			}
			i++;
		}
		tx = tdb.findDataByKeyAndVal("id", srcId);
		tdb.DBClose();
		/*
		 * 这里获得待检测的文章标题和内容
		 */
		textname = tx.getTitle(); // 输入待检测文章的标题
		pagetext = Text.content2String(tx.getContent()); // 输入待检测文章的内容

		lsh.setPatternSenFrom(lsh.getNumberOfSen());
		lsh.createTableSin(pagetext, textname, i);
		lsh.setPatternSenTo(lsh.getNumberOfSen() - 1);

		lsh.setNumberOfText(i + 1);

		/*
		 * 核心 以上为准备阶段
		 */
		lsh.run();
		/*
		 * 以下为输出阶段 strdb为输出到对应数据库的内容
		 */
		String strdb = lsh.writeToDBSimi();
		/*
		 * 相关操作
		 */
		
		//将算法结果输出到控制台 供检查
//		logger.info("-----以下输出lsh算法处理后的内容-----");
//		logger.info(strdb);
		
		Document detail = Similarity.string2Document(strdb, srcId);
		// 创建一个Similarity对象存储算法处理过的数据并插入数据库中 总相似度暂时未计算
		Similarity sim = new Similarity(srcId, detail, 0.0);
		SimilarityDB sdb = new SimilarityDB();
		sdb.insertData(sim);
		sdb.DBClose();
	}
	
	/*
	 * 该函数负责获取Lsh算法的输入 输入从相关数据库中获取 文章内容必须完整 包括 换行 需要传入用户输入的文章的id
	 * 同时该函数包含分词，区别于上面的k-shingle
	 */
	public void LshPageFromDBNo(String srcId) {
		Logger logger = Config.getLogger(this.getClass());
		LshCoreNo lsh = new LshCoreNo();
		String textname;
		String pagetext;
		// 获得RalationMap数据库信息 一片源文章对应多少篇爬取的文章
		RalationMapDB rmdb = new RalationMapDB();
		RalationMap rm = rmdb.findDataByKeyAndVal("srcId", srcId);
		rmdb.DBClose();
		if (rm == null) {
			logger.error("-----[警告]数据库中未找到" + srcId + "对应的源文章-----");
			return;
		}
		int tarAmount = rm.getTarAmount();
		if (tarAmount == 0) {
			logger.error("-----[警告]该源文章" + srcId + "对应的爬取文章数为0-----");
			return;
		}
		int i = 0; // 标记属于第几篇文章
		// 获取爬取文章全部的id
		List<String> tarIdAll = rm.getTarIdAll();
		TextDB tdb = new TextDB();
		Text tx;
		while (i < tarAmount) { // while 循环获得爬取下来的每篇文章的标题和内容
			String tarId = tarIdAll.get(i);
			tx = tdb.findDataByKeyAndVal("id", tarId);
			if (tx == null) {
				logger.error("-----" + tarId + "未找到对应目标文章-----");
			} else {
				/*
				 * 这里获得爬取下来的每篇文章的标题和内容 ，直至所有文章获取通过
				 */
				textname = tx.getId(); // 输入每篇文章的标题(用id代替
				pagetext = Text.content2String(tx.getContent()); // 输入每篇文章的内容
//				logger.info("----- 以下是待检测文章 : "+tx.getTitle()+"的内容-----");
//				logger.info(pagetext);
				
				lsh.createTableSinNo(pagetext, textname, i);
			}
			i++;
		}
		tx = tdb.findDataByKeyAndVal("id", srcId);
		tdb.DBClose();
		/*
		 * 这里获得待检测的文章标题和内容
		 */
		textname = tx.getTitle(); // 输入待检测文章的标题
		pagetext = Text.content2String(tx.getContent()); // 输入待检测文章的内容

		lsh.setPatternSenFrom(lsh.getNumberOfSen());
		lsh.createTableSinNo(pagetext, textname, i);
		lsh.setPatternSenTo(lsh.getNumberOfSen() - 1);

		lsh.setNumberOfText(i + 1);

		/*
		 * 核心 以上为准备阶段
		 */
		lsh.run();
		/*
		 * 以下为输出阶段 strdb为输出到对应数据库的内容
		 */
		String strdb = lsh.writeToDBSimi();
		/*
		 * 相关操作
		 */
		
		//将算法结果输出到控制台 供检查
//		logger.info("-----以下输出lsh算法处理后的内容-----");
//		logger.info(strdb);
		
		Document detail = Similarity.string2Document(strdb, srcId);
		// 创建一个Similarity对象存储算法处理过的数据并插入数据库中 总相似度暂时未计算
		Similarity sim = new Similarity(srcId, detail, 0.0);
		SimilarityDB sdb = new SimilarityDB();
		sdb.insertData(sim);
		sdb.DBClose();
	}

	/*
	 * 该函数负责获取Lsh算法的输入 输入从文本文档中获取 artilepath:爬虫文件路径 patternpath：待检测文章路径
	 * outputpath:输出文件路径
	 */

	public void LshPageFromDoc(String artilepath, String patternpath, String outputpath) {
		LshCoreNo lsh = new LshCoreNo();
		SelfFile selfFile = new SelfFile();
		String[] artics = selfFile.ShowDirListPath(artilepath);
		int numberOfText = artics.length + 1;
		lsh.setNumberOfText(numberOfText);

		String textname;
		String pagetext;
		boolean b = true;
		int i = 0; // 标记属于第几篇文章
		while (i < artics.length) { // while 循环获得爬取下来的每篇文章的标题和内容

			/*
			 * 这里获得爬取下来的每篇文章的标题和内容 ，直至所有文章获取通过
			 */
			String structure = "";
			String temp_f = artics[i].split("/")[artics[i].split("/").length - 1];
			String regex = "^[\\u0020\\u3000]*$";
			SelfFile selfFileD = new SelfFile(artics[i]);
			String text_buffer = "";
			StringBuilder sreb = new StringBuilder();
			while (selfFileD.getpatternPara()) {
				sreb.append(selfFileD.getText() + "\n");
			}
			textname = temp_f; // 输入每篇文章的标题
			pagetext = sreb.toString(); // 输入每篇文章的内容
			System.out.println(pagetext);
			lsh.createTableSin(pagetext, textname, i);
			i++;
		}

		/*
		 * 这里获得待检测的文章标题和内容
		 */
		textname = patternpath.split("/")[patternpath.split("/").length - 1]; // 输入待检测文章的标题
		SelfFile sek = new SelfFile(patternpath);
		StringBuilder sreb2 = new StringBuilder();
		while (sek.getpatternPara()) {
			sreb2.append(sek.getText() + "\n");
		}
		pagetext = sreb2.toString(); // 输入待检测文章的内容

		lsh.setPatternSenFrom(lsh.getNumberOfSen());
		lsh.createTableSin(pagetext, textname, i);
		lsh.setPatternSenTo(lsh.getNumberOfSen() - 1);

		/*
		 * 核心 以上为准备阶段
		 */
		lsh.run();
		/*
		 * 以下为输出阶段
		 */
		lsh.writeToFileSimi(outputpath);

	}

	/*
	 * 该函数负责获取Lsh算法的输入 输入从文本文档中获取 artilepath:爬虫文件路径 patternpath：待检测文章路径
	 * outputpath:输出文件路径
	 * 该函数包含分词  
	 */

	public void LshPageFromDocNo(String artilepath, String patternpath, String outputpath) {
		LshCoreNo lsh = new LshCoreNo();
		SelfFile selfFile = new SelfFile();
		String[] artics = selfFile.ShowDirListPath(artilepath);
		int numberOfText = artics.length + 1;
		lsh.setNumberOfText(numberOfText);

		String textname;
		String pagetext;
		boolean b = true;
		int i = 0; // 标记属于第几篇文章
		while (i < artics.length) { // while 循环获得爬取下来的每篇文章的标题和内容

			/*
			 * 这里获得爬取下来的每篇文章的标题和内容 ，直至所有文章获取通过
			 */
			String structure = "";
			String temp_f = artics[i].split("/")[artics[i].split("/").length - 1];
			String regex = "^[\\u0020\\u3000]*$";
			SelfFile selfFileD = new SelfFile(artics[i]);
			String text_buffer = "";
			StringBuilder sreb = new StringBuilder();
			while (selfFileD.getpatternPara()) {
				sreb.append(selfFileD.getText() + "\n");
			}
			textname = temp_f; // 输入每篇文章的标题
			pagetext = sreb.toString(); // 输入每篇文章的内容
			System.out.println(pagetext);
			lsh.createTableSinNo(pagetext, textname, i);
			i++;
		}

		/*
		 * 这里获得待检测的文章标题和内容
		 */
		textname = patternpath.split("/")[patternpath.split("/").length - 1]; // 输入待检测文章的标题
		SelfFile sek = new SelfFile(patternpath);
		StringBuilder sreb2 = new StringBuilder();
		while (sek.getpatternPara()) {
			sreb2.append(sek.getText() + "\n");
		}
		pagetext = sreb2.toString(); // 输入待检测文章的内容

		lsh.setPatternSenFrom(lsh.getNumberOfSen());
		lsh.createTableSinNo(pagetext, textname, i);
		lsh.setPatternSenTo(lsh.getNumberOfSen() - 1);

		/*
		 * 核心 以上为准备阶段
		 */
		lsh.run();
		/*
		 * 以下为输出阶段
		 */
		lsh.writeToFileSimi(outputpath);

	}
	/*
	 * 该函数负责获取Kmp算法的输入 输入从相关数据库中获取 artilepath:爬虫文件路径 patternpath：待检测文章路径
	 * outputpath:输出文件路径
	 */

	public void KmpPageFromDB(String srcId) {
		Logger logger = Config.getLogger(this.getClass());
		String textname;
		String pagetext;
		String patterntext;
		/*
		 * 以下从相应的数据库获取 待检测文章的内容 保存在patterntext里面
		 */
		TextDB tdb = new TextDB();
		Text tx = tdb.findDataByKeyAndVal("id", srcId);
		if (tx == null) {
			logger.error("-----标题---" + srcId + "---未找到对应目标文章-----");
			return;
		}
		patterntext = Text.content2String(tx.getContent()); // 输入待检测文章的内容

		KmpCoreNo kmp = new KmpCoreNo();
		// 获得RalationMap数据库信息 一片源文章对应多少篇爬取的文章
		RalationMapDB rmdb = new RalationMapDB();
		RalationMap rm = rmdb.findDataByKeyAndVal("srcId", srcId);
		rmdb.DBClose();
		if (rm == null) {
			logger.error("-----[警告]数据库中未找到---" + srcId + "---对应的源文章-----");
			return;
		}
		int tarAmount = rm.getTarAmount();
		if (tarAmount == 0) {
			logger.error("-----[警告]该源文章" + srcId + "对应的爬取文章数为0-----");
			return;
		}
		// 获取爬取文章全部的id
		List<String> tarIdAll = rm.getTarIdAll();
		// 建立TextDB数据库连接
		int i = 0; // 标记属于第几篇文章
		while (i < tarAmount) { // while 循环获得爬取下来的每篇文章的标题和内容
			String tarId = tarIdAll.get(i);
			tx = tdb.findDataByKeyAndVal("id", tarId);
			if (tx == null) {
				logger.error("-----" + tarId + "未找到对应目标文章-----");
			} else {
				/*
				 * 这里获得爬取下来的每篇文章的标题和内容 ，直至所有文章获取通过
				 */
				textname = tx.getId(); // 输入每篇文章的标题(用id代替
				pagetext = Text.content2String(tx.getContent()); // 输入每篇文章的内容
				kmp.kmpJob(patterntext, pagetext, i, textname);
			}
			i++;
			/*
			 * 这里获得爬取下来的每篇文章的标题和内容 ，直至所有文章获取通过
			 */
		}
		tdb.DBClose();
		/*
		 * 以下为输出阶段 strdb为输出到对应数据库的内容
		 */
		String strdb = kmp.writeToDBSimi();
		/*
		 * 相关操作
		 */
//		logger.info("-----以下输出kmp算法处理后的内容-----");
//		logger.info(strdb);
		Document detail = Similarity.string2Document(strdb, srcId);
		// 创建一个Similarity对象存储算法处理过的数据并插入数据库中 总相似度暂时未计算
		Similarity sim = new Similarity(srcId, detail, 0.0);
		SimilarityDB sdb = new SimilarityDB();
		sdb.insertData(sim);
		sdb.DBClose();
	}

	/*
	 * 该函数负责获取Kmp算法的输入 输入从文本文档中获取 artilepath:爬虫文件路径 patternpath：待检测文章路径
	 * outputpath:输出文件路径
	 */

	public void KmpPageFromDoc(String artilepath, String patternpath, String outputpath) {
		String textname;
		String pagetext;
		String patterntext;
		/*
		 * 以下从相应的文件中获取 待检测文章的内容 保存在patterntext里面
		 */
		SelfFile sek = new SelfFile(patternpath);
		StringBuilder sreb2 = new StringBuilder();
		while (sek.getpatternPara()) {
			sreb2.append(sek.getText() + "\n");
		}
		patterntext = sreb2.toString();

		KmpCoreNo kmp = new KmpCoreNo();
		SelfFile selfFile = new SelfFile();
		String[] artics = selfFile.ShowDirListPath(artilepath);
		int i = 0; // 标记属于第几篇文章
					// while 循环获得爬取下来的每篇文章的标题和内容
		while (i < artics.length) {
			/*
			 * 这里获得爬取下来的每篇文章的标题和内容 ，直至所有文章获取通过
			 */
			SelfFile selfFileD = new SelfFile(artics[i]);
			StringBuilder sreb = new StringBuilder();
			while (selfFileD.getpatternPara()) {
				sreb.append(selfFileD.getText() + "\n");
			}
			textname = artics[i].split("/")[artics[i].split("/").length - 1]; // 输入每篇文章的标题
			pagetext = sreb.toString(); // 输入每篇文章的内容
			System.out.println(pagetext);
			System.out.println("***" + i);

			kmp.kmpJob(patterntext, pagetext, i, textname);
			i++;
		}
		/*
		 * 以下为输出阶段 strdb为输出到文本的内容
		 */
		kmp.writeToFileSimi(outputpath);

	}

	/*
	 * 该函数负责LSH比较两篇文章的相似度
	 * 采用minhash签名进行比较
	 * 使用相关数据库
	 */
	public void LshCorePage2PageFromDB(String srcId){
		Logger logger = Config.getLogger(this.getClass());
		LshCorePageNo lshPage = new LshCorePageNo();
		String textname;
		String pagetext;
		// 获得RalationMap数据库信息 一片源文章对应多少篇爬取的文章
		RalationMapDB rmdb = new RalationMapDB();
		RalationMap rm = rmdb.findDataByKeyAndVal("srcId", srcId);
		rmdb.DBClose();
		if (rm == null) {
			logger.error("-----[警告]数据库中未找到" + srcId + "对应的源文章-----");
			return;
		}
		int tarAmount = rm.getTarAmount();
		if (tarAmount == 0) {
			logger.error("-----[警告]该源文章" + srcId + "对应的爬取文章数为0-----");
			return;
		}
		int i = 0; // 标记属于第几篇文章
		// 获取爬取文章全部的id
		List<String> tarIdAll = rm.getTarIdAll();
		TextDB tdb = new TextDB();
		Text tx;
		while (i < tarAmount) { // while 循环获得爬取下来的每篇文章的标题和内容
			String tarId = tarIdAll.get(i);
			tx = tdb.findDataByKeyAndVal("id", tarId);
			if (tx == null) {
				logger.error("-----" + tarId + "未找到对应目标文章-----");
			} else {
				/*
				 * 这里获得爬取下来的每篇文章的标题和内容 ，直至所有文章获取通过
				 */
				textname = tx.getId(); // 输入每篇文章的标题(用id代替
				pagetext = Text.content2String(tx.getContent()); // 输入每篇文章的内容
//				logger.info("----- 以下是待检测文章 : "+tx.getTitle()+"的内容-----");
//				logger.info(pagetext);
				
				lshPage.createTableSin(pagetext, textname, i);
			}
			i++;
		}
		tx = tdb.findDataByKeyAndVal("id", srcId);
		tdb.DBClose();
		/*
		 * 这里获得待检测的文章标题和内容
		 */
		textname = tx.getTitle(); // 输入待检测文章的标题
		pagetext = Text.content2String(tx.getContent()); // 输入待检测文章的内容

		lshPage.createTableSin(pagetext, textname, i);


		/*
		 * 核心 以上为准备阶段
		 */
		lshPage.run();
		/*
		 * 以下为输出阶段 strdb为输出到对应数据库的内容
		 */
		String strdb = lshPage.writeToDBSimi();
		/*
		 * 相关操作
		 */
		
		//将算法结果输出到控制台 供检查
//		logger.info("-----以下输出lsh算法处理后的内容-----");
//		logger.info(strdb);
		
		Document detail = Similarity.string2Document(strdb, srcId);
		// 创建一个Similarity对象存储算法处理过的数据并插入数据库中 总相似度暂时未计算
		Similarity sim = new Similarity(srcId, detail, 0.0);
		SimilarityDB sdb = new SimilarityDB();
		sdb.insertData(sim);
		sdb.DBClose();
	}
	
	
	/*
	 * 该函数负责LSH比较两篇文章的相似度
	 * 采用minhash签名进行比较
	 * 数据采用传统的文件存储形式
	 */
	public void LshCorePage2PageFromDoc(String artilepath, String patternpath, String outputpath) {
		LshCorePageNo lsh = new LshCorePageNo();
		SelfFile selfFile = new SelfFile();
		String[] artics = selfFile.ShowDirListPath(artilepath);
		int numberOfText = artics.length + 1;

		String textname;
		String pagetext;
		int i = 0; // 标记属于第几篇文章
		while (i < artics.length) { // while 循环获得爬取下来的每篇文章的标题和内容

			/*
			 * 这里获得爬取下来的每篇文章的标题和内容 ，直至所有文章获取通过
			 */
			String structure = "";
			String temp_f = artics[i].split("/")[artics[i].split("/").length - 1];
			String regex = "^[\\u0020\\u3000]*$";
			SelfFile selfFileD = new SelfFile(artics[i]);
			String text_buffer = "";
			StringBuilder sreb = new StringBuilder();
			while (selfFileD.getpatternPara()) {
				sreb.append(selfFileD.getText() + "\n");
			}
			textname = temp_f; // 输入每篇文章的标题
			pagetext = sreb.toString(); // 输入每篇文章的内容
			lsh.createTableSin(pagetext, textname, i);
			i++;
		}

		/*
		 * 这里获得待检测的文章标题和内容
		 */
		textname = patternpath.split("/")[patternpath.split("/").length - 1]; // 输入待检测文章的标题
		SelfFile sek = new SelfFile(patternpath);
		StringBuilder sreb2 = new StringBuilder();
		while (sek.getpatternPara()) {
			sreb2.append(sek.getText() + "\n");
		}
		pagetext = sreb2.toString(); // 输入待检测文章的内容

		
		lsh.createTableSin(pagetext, textname, i);

		/*
		 * 核心 以上为准备阶段
		 */
		lsh.run();
		/*
		 * 以下为输出阶段
		 */
		lsh.writeToFileSimi(outputpath);

	}

	public static void main(String[] args) {
		PageInOut o = new PageInOut();
		String artilepath = "C:\\Users\\asus\\workspace\\Detection1.1\\resultFiles";
		String patternpath = "C:\\Users\\asus\\workspace\\Detection1.1\\srcTxtFiles\\分布式网络爬虫.txt";
		String outputpath = "C:\\Users\\asus\\workspace\\Detection1.1\\output\\g00656c.txt";
		o.LshPageFromDocNo(artilepath, patternpath, outputpath);

	}

}
